package com.runa.monitor.platinterface.netservice.equipment;

import com.alibaba.fastjson.JSON;
import com.runa.monitor.comm.dto.*;
import com.runa.monitor.platinterface.backwork.function.TaskFunction;
import com.runa.monitor.platinterface.netservice.connect.commstatus.CommStatus;
import com.runa.monitor.platinterface.platService.RepositoryService;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.jjn.Jjn8124RequestData;
import com.runa.rccprotocol.dto.param.ExtendParam;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Slf4j
public class Jjn8124Driver extends NetEqu<String> {


    public Jjn8124Driver(String serial, Integer timeout) {
        super(serial, timeout);
    }

    @Override
    public void readNodeEqu(List<Node> nodeList, TaskFunction function, EquData.EquDataType type) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, nodeList);
            return;
        }
        switch (type) {
            case METER:
                readHeatMeter(nodeList, function);
                break;
            case VALVE:
                readHouseValve(nodeList, function);
                break;
            default:
        }
    }


    private void readHeatMeter(List<Node> meters, TaskFunction function) {
        log.info("嘉洁能抄表meters---" + JSON.toJSONString(meters));
        for (Node node : meters) {
            Jjn8124RequestData requestData = new Jjn8124RequestData(serial());
            requestData.readMeter("", node.getSerial());
            requestData.setRemain(Collections.singletonList(node));
            sendRequest(requestData, function);
        }
    }

    public static void main(String[] args) {
        Jjn8124RequestData requestData = new Jjn8124RequestData("9311519137");
        requestData.readMeter("", "00312921340483");
        System.out.println(ByteUtil.byteToHexString((byte[]) requestData.getData()));
        requestData = new Jjn8124RequestData("9311519137");
        requestData.readMeter("", "00312922180662");
        System.out.println(ByteUtil.byteToHexString((byte[]) requestData.getData()));
        requestData = new Jjn8124RequestData("9311519137");
        requestData.readMeter("", "00312922700429");
        System.out.println(ByteUtil.byteToHexString((byte[]) requestData.getData()));
    }

    private void readHouseValve(List<Node> valves, TaskFunction function) {
        for (Node node : valves) {
            Jjn8124RequestData requestData = new Jjn8124RequestData(serial());
            requestData.readValve(node.getSerial());
            requestData.setRemain(Collections.singletonList(node));
            sendRequest(requestData, function);
        }
    }

    @Override
    public void setNodeEquArchive(List<Archive> archives, TaskFunction function) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, archives);
            return;
        }
        Jjn8124RequestData requestData = new Jjn8124RequestData(serial());
        requestData.setEnable();
        sendRequest(requestData, null);
        List<String[]> equipment = new ArrayList<>();
        List<Integer> index = new ArrayList<>();
        String serial = function.getSerial();
        for (Archive archive : archives) {
            RunaEquArchive meterArchive = (RunaEquArchive) archive;
            Node node = findMeter(meterArchive.getSerial(), serial);
            if (node == null) {
                node = findValve(meterArchive.getSerial(), serial);
            }
            if (node != null) {
                equipment.add(new String[]{node.getSerial(), node.getModel()});
                index.add(meterArchive.getIndex());
            }
            if (equipment.size() == 32) {
                requestData.setRemain(index);
                equipment.clear();
                index = new ArrayList<>();
                requestData.register(equipment);
                sendRequest(requestData, function);
            }
        }
        if (!equipment.isEmpty()) {
            requestData.register(equipment);
            sendRequest(requestData, function);
        }
    }

    @Override
    public void clearNodeEquArchive(TaskFunction function) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, null);
            return;
        }
        Jjn8124RequestData requestData = new Jjn8124RequestData(serial());
        requestData.logout(repositoryService.getCommValveByNetSerial(commNetEquipment.getId()).size() + repositoryService.getCommMeterByNetSerial(commNetEquipment.getId()).size());
        sendRequest(requestData, function);
    }

    @Override
    public void valveOnOffControl(List<Node> valves, boolean ifLock, Integer opening, TaskFunction function) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, valves);
            return;
        }
        for (Node valve : valves) {
            Jjn8124RequestData requestData = new Jjn8124RequestData(serial());
            if (valve != null) {
                requestData.setValve(valve.getSerial(), opening > 0);
                requestData.setRemain(valve);
                sendRequest(requestData, function);
            }
        }
    }

    @Override
    public void readNodeRecord(List<Integer> indexes, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitRecord(List<Node> valveSerial, Integer model, Map param, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitModel(List<Node> valveSerial, boolean model, TaskFunction function) {

    }

    @Override
    public void sentExtendParam(ExtendParam param, TaskFunction function) {

    }

    @Override
    public void readPublicUnitRecord(Node valveSerial, Integer model, TaskFunction function) {

    }

    @Override
    public void readPublicUnitAndMeter(Node valveSerial, Node meterSerial, TaskFunction function) {

    }

    @Override
    public void heartbeatUpdate() {

    }

    @Override
    public boolean heartStop() {
        return false;
    }

//    public Meter findMeter(String serial) {
//        for (Node meter : meters) {
//            if (serial.equals(meter.getSerial())) {
//                return (Meter) meter;
//            }
//        }
//        return null;
//    }
//
//    public Valve findValve(String serial) {
//        for (Node valve : valves) {
//            if (serial.equals(valve.getSerial())) {
//                return (Valve) valve;
//            }
//        }
//        return null;
//    }
//
//    @Override
//    public Node findPanel(String serial) {
//        return null;
//    }
//
//    @Override
//    public Node findUnit(String serial) {
//        return null;
//    }
}
